using System;
using System.Data;
using System.Data.Common;
using System.Text.RegularExpressions;
using Widgetsphere.Core.Logging;
using DbHelp = Widgetsphere.Core.DataAccess.DatabaseHelper;


namespace Widgetsphere.Core.DataAccess
{
	[System.ComponentModel.DesignerCategoryAttribute("code")]
	public abstract partial class DomainCollectionBase : DataTable, IDomainCollection
	{
		protected string ConnectionString
		{
			get
			{
				var sdBase = (SubDomainBase)this.DataSet;
				return sdBase.ConnectionString;
			}
		}

		int IDomainCollection.Count
		{
			get { return this.Rows.Count; }
		}

		public void RunSelectCommand(SelectCommand rule)
		{
			var fillCommand = PersistableDomainCollectionBase.GetFillCommand(rule.ConnectionString, rule.StoredProcedureName);
			foreach (string paramKey in rule.ParameterValues.Keys)
			{
				PersistableDomainCollectionBase.SetParameterValue(fillCommand, paramKey, rule.ParameterValues[paramKey]);
			}

			if (rule.TimeOut > 0)
				fillCommand.CommandTimeout = rule.TimeOut;

			this.FillDataTable(rule.ConnectionString, fillCommand);
		}

		public static IDbCommand GetFillCommand(string connectionString, string spName)
		{

			var sp = StoredProcedureFactory.GetStoredProcedure(connectionString, spName);
			return sp.GetDataSetCommand();
		}

		public void FillDataTable(string connectionString, IDbCommand selectCommand)
		{
			try
			{
				var da = DbHelp.GetDataAdapter();
				SetTableMappings(ref da);
				da.SelectCommand = selectCommand;
				DbHelp.SetConnections(da, DbHelp.GetConnection(connectionString));
				DbHelp.Fill(da, this);
			}
			catch (Exception ex)
			{
			MessageLog.LogError(LogClass.WSCommonDataAccess, ex);
				var drErrors = this.GetErrors();
				if (drErrors.Length > 0)
				{
					System.Diagnostics.Debug.WriteLine(String.Format("Error In Table: {0}", this.TableName));
				}
				foreach (var dr in drErrors)
				{
					foreach (var dc in dr.GetColumnsInError())
					{
						System.Diagnostics.Debug.WriteLine(String.Format("Column: {0} - Error : {1}", dc.ColumnName, dr.GetColumnError(dc)));
					}
				}
				throw;
			}
		}

		protected void SetTableMappings(ref IDbDataAdapter da)
		{
			var tableMap = new DataTableMapping("Table", this.TableName);
			foreach (DataColumn dc in this.Columns)
			{
				tableMap.ColumnMappings.Add(DataColumnNameToParameterName(dc.ColumnName), dc.ColumnName);
			}
			da.TableMappings.Add(tableMap);
		}

		protected static string DataColumnNameToParameterName(string dataColumnName)
		{
			var digitregex = new Regex("(?<caps>[A-Z,_])");
			var parameterName = digitregex.Replace(dataColumnName, "_$+");
			parameterName = parameterName.ToLower().TrimStart('_');
			return parameterName;
		}

		public bool IsColumnInPrimaryKey(DataColumn dataColumn)
		{
			foreach (var dc in this.PrimaryKey)
			{
				if (dataColumn == dc)
					return true;
			}
			return false;
		}



	}
}
